package com.lifeverse.entity;

import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Set;

/**
 * 生命体群体实体类
 * 表示生命体的分组和群体智慧
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "life_entity_groups", indexes = {
    @Index(name = "idx_group_type", columnList = "group_type"),
    @Index(name = "idx_group_status", columnList = "group_status"),
    @Index(name = "idx_group_size", columnList = "member_count"),
    @Index(name = "idx_group_wisdom_score", columnList = "wisdom_score")
})
public class LifeEntityGroup extends BaseEntity {
    
    /**
     * 群体类型枚举
     */
    public enum GroupType {
        COLLABORATION("协作群体", "为了共同目标而协作的群体"),
        COMMUNITY("社区群体", "基于地理位置或共同兴趣的群体"),
        INDUSTRY("行业群体", "同一行业或领域的群体"),
        ECOSYSTEM("生态群体", "形成生态系统的群体"),
        NETWORK("网络群体", "基于网络连接的群体"),
        TEMPORARY("临时群体", "为了特定任务临时组建的群体"),
        PERMANENT("永久群体", "长期存在的稳定群体"),
        HIERARCHICAL("层级群体", "具有层级结构的群体"),
        FLAT("扁平群体", "扁平化结构的群体"),
        DYNAMIC("动态群体", "成员动态变化的群体");
        
        private final String displayName;
        private final String description;
        
        GroupType(String displayName, String description) {
            this.displayName = displayName;
            this.description = description;
        }
        
        public String getDisplayName() {
            return displayName;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 群体状态枚举
     */
    public enum GroupStatus {
        FORMING("组建中", "群体正在组建过程中"),
        ACTIVE("活跃", "群体正常活跃运行"),
        DORMANT("休眠", "群体暂时不活跃"),
        EVOLVING("进化中", "群体正在进化和改变"),
        DISSOLVING("解散中", "群体正在解散"),
        DISSOLVED("已解散", "群体已经解散");
        
        private final String displayName;
        private final String description;
        
        GroupStatus(String displayName, String description) {
            this.displayName = displayName;
            this.description = description;
        }
        
        public String getDisplayName() {
            return displayName;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 群体名称
     */
    @Column(name = "group_name", nullable = false, length = 100)
    private String groupName;
    
    /**
     * 群体类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "group_type", nullable = false, length = 20)
    private GroupType groupType;
    
    /**
     * 群体状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "group_status", nullable = false, length = 20)
    private GroupStatus groupStatus = GroupStatus.FORMING;
    
    /**
     * 群体描述
     */
    @Column(name = "description", length = 500)
    private String description;
    
    /**
     * 群体成员
     */
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
        name = "group_members",
        joinColumns = @JoinColumn(name = "group_id"),
        inverseJoinColumns = @JoinColumn(name = "entity_id")
    )
    private Set<LifeEntity> members;
    
    /**
     * 群体领导者
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "leader_id")
    private LifeEntity leader;
    
    /**
     * 成员数量
     */
    @Column(name = "member_count", nullable = false)
    private Integer memberCount = 0;
    
    /**
     * 群体智慧评分（0-100）
     */
    @Column(name = "wisdom_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal wisdomScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体凝聚力（0-100）
     */
    @Column(name = "cohesion_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal cohesionScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体效率（0-100）
     */
    @Column(name = "efficiency_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal efficiencyScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体创新能力（0-100）
     */
    @Column(name = "innovation_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal innovationScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体协作能力（0-100）
     */
    @Column(name = "collaboration_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal collaborationScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体学习能力（0-100）
     */
    @Column(name = "learning_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal learningScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体适应能力（0-100）
     */
    @Column(name = "adaptability_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal adaptabilityScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体稳定性（0-100）
     */
    @Column(name = "stability_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal stabilityScore = BigDecimal.valueOf(50.00);
    
    /**
     * 群体多样性指数（0-100）
     */
    @Column(name = "diversity_index", nullable = false, precision = 5, scale = 2)
    private BigDecimal diversityIndex = BigDecimal.valueOf(50.00);
    
    /**
     * 群体活跃度（0-100）
     */
    @Column(name = "activity_level", nullable = false, precision = 5, scale = 2)
    private BigDecimal activityLevel = BigDecimal.valueOf(50.00);
    
    /**
     * 群体目标
     */
    @Column(name = "objectives", columnDefinition = "TEXT")
    private String objectives;
    
    /**
     * 群体规则
     */
    @Column(name = "rules", columnDefinition = "TEXT")
    private String rules;
    
    /**
     * 群体文化
     */
    @Column(name = "culture", columnDefinition = "TEXT")
    private String culture;
    
    /**
     * 群体知识库
     */
    @Column(name = "knowledge_base", columnDefinition = "TEXT")
    private String knowledgeBase;
    
    /**
     * 群体决策历史
     */
    @Column(name = "decision_history", columnDefinition = "TEXT")
    private String decisionHistory;
    
    /**
     * 群体统计数据
     */
    @Column(name = "statistics", columnDefinition = "TEXT")
    private String statistics;
    
    /**
     * 群体标签
     */
    @Column(name = "tags", length = 200)
    private String tags;
    
    /**
     * 群体属性
     */
    @Column(name = "attributes", columnDefinition = "TEXT")
    private String attributes;
    
    /**
     * 群体创建时间
     */
    @Column(name = "formed_at", nullable = false)
    private LocalDateTime formedAt;
    
    /**
     * 最后活动时间
     */
    @Column(name = "last_activity_at")
    private LocalDateTime lastActivityAt;
    
    /**
     * 群体解散时间
     */
    @Column(name = "dissolved_at")
    private LocalDateTime dissolvedAt;
    
    /**
     * 是否公开群体
     */
    @Column(name = "is_public", nullable = false)
    private Boolean isPublic = true;
    
    /**
     * 是否允许自由加入
     */
    @Column(name = "allow_free_join", nullable = false)
    private Boolean allowFreeJoin = false;
    
    /**
     * 最大成员数量
     */
    @Column(name = "max_members")
    private Integer maxMembers;
    
    /**
     * 最小成员数量
     */
    @Column(name = "min_members")
    private Integer minMembers = 2;
    
    @PrePersist
    protected void onCreate() {
        super.onCreate();
        if (formedAt == null) {
            formedAt = LocalDateTime.now();
        }
        if (lastActivityAt == null) {
            lastActivityAt = LocalDateTime.now();
        }
    }
    
    /**
     * 更新最后活动时间
     */
    public void updateLastActivityTime() {
        this.lastActivityAt = LocalDateTime.now();
    }
    
    /**
     * 添加成员
     */
    public void addMember(LifeEntity entity) {
        if (members != null) {
            members.add(entity);
            this.memberCount = members.size();
            updateLastActivityTime();
        }
    }
    
    /**
     * 移除成员
     */
    public void removeMember(LifeEntity entity) {
        if (members != null) {
            members.remove(entity);
            this.memberCount = members.size();
            updateLastActivityTime();
        }
    }
    
    /**
     * 激活群体
     */
    public void activate() {
        this.groupStatus = GroupStatus.ACTIVE;
        updateLastActivityTime();
    }
    
    /**
     * 休眠群体
     */
    public void dormant() {
        this.groupStatus = GroupStatus.DORMANT;
    }
    
    /**
     * 解散群体
     */
    public void dissolve() {
        this.groupStatus = GroupStatus.DISSOLVED;
        this.dissolvedAt = LocalDateTime.now();
    }
    
    /**
     * 判断群体是否活跃
     */
    public boolean isActive() {
        return groupStatus == GroupStatus.ACTIVE;
    }
    
    /**
     * 判断群体是否健康
     */
    public boolean isHealthy() {
        return wisdomScore.compareTo(BigDecimal.valueOf(60)) >= 0 
               && cohesionScore.compareTo(BigDecimal.valueOf(60)) >= 0
               && memberCount >= minMembers;
    }
    
    /**
     * 判断群体是否稳定
     */
    public boolean isStable() {
        return stabilityScore.compareTo(BigDecimal.valueOf(70)) >= 0;
    }
    
    /**
     * 判断群体是否高效
     */
    public boolean isEfficient() {
        return efficiencyScore.compareTo(BigDecimal.valueOf(70)) >= 0;
    }
    
    /**
     * 判断群体是否创新
     */
    public boolean isInnovative() {
        return innovationScore.compareTo(BigDecimal.valueOf(70)) >= 0;
    }
    
    /**
     * 计算群体综合评分
     */
    public BigDecimal calculateOverallScore() {
        return wisdomScore
                .add(cohesionScore)
                .add(efficiencyScore)
                .add(innovationScore)
                .add(collaborationScore)
                .add(learningScore)
                .add(adaptabilityScore)
                .add(stabilityScore)
                .divide(BigDecimal.valueOf(8), 2, java.math.RoundingMode.HALF_UP);
    }
    
    /**
     * 获取群体存在时间（天数）
     */
    public long getExistenceDays() {
        LocalDateTime endTime = dissolvedAt != null ? dissolvedAt : LocalDateTime.now();
        return java.time.temporal.ChronoUnit.DAYS.between(formedAt, endTime);
    }
    
    /**
     * 判断是否可以加入新成员
     */
    public boolean canAddMember() {
        return groupStatus == GroupStatus.ACTIVE 
               && (maxMembers == null || memberCount < maxMembers);
    }
    
    /**
     * 判断成员数量是否足够
     */
    public boolean hasSufficientMembers() {
        return memberCount >= minMembers;
    }
}